package com.topisv.tms.rest;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXB;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.topisv.tms.entity.CheckInOrOut;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.stock.ViewMainCusStock;
import com.topisv.tms.entity.stock.instorage.MDHouseConfig;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.exception.ErrorCode;
import com.topisv.tms.exception.PaiUException;
import com.topisv.tms.rest.entity.md.request.CancelOrderRequestBody;
import com.topisv.tms.rest.entity.md.request.StockQueryRequestBody;
import com.topisv.tms.rest.entity.md.request.TransferBodyContent;
import com.topisv.tms.rest.entity.md.request.TransferData;
import com.topisv.tms.rest.entity.md.response.Response;
import com.topisv.tms.rest.entity.md.response.ResponseBody;
import com.topisv.tms.rest.entity.md.response.StockQueryRecordDetail;
import com.topisv.tms.rest.entity.md.response.StockQueryResponseBody;
import com.topisv.tms.service.EdiOrderService;
import com.topisv.tms.service.md.MDCheckInOrOutService;
import com.topisv.tms.service.md.MDHouseConfigService;
import com.topisv.tms.service.md.MdBusinessExecutor;
import com.topisv.tms.service.md.MdCallBackAdapter;
import com.topisv.tms.service.md.MdSendOutTaskService;
import com.topisv.tms.service.stock.ViewMainCusStockService;
import com.topisv.tms.service.stock.preinstorage.PreInstorageService;
import com.topisv.tms.service.ulorder.UlorderService;
import com.topisv.tms.service.work.WorkOrderService;
import com.topisv.tms.tools.TransferHelper;
import com.topisv.tms.utils.WmsContants;
import com.topisv.tms.utils.enums.MDOrderType;
import com.topisv.tms.utils.vo.PreInstorageVo;

/**
 * 批次的Restful API的Controller.
 * 
 * @author calvin
 */
@Controller
@RequestMapping(value = "/api/mid")
public class MidRestController {

	private static final Logger logger = LoggerFactory.getLogger(MidRestController.class);
	@Autowired
	private ViewMainCusStockService viewMainCusStockService;

	@Autowired
	private EdiOrderService ediOrderService;
	
	@Autowired
	private UlorderService ulorderService;

	@Autowired
	private WorkOrderService workOrderService;

	@Autowired
	private MdBusinessExecutor mdExecutor;
	@Autowired
	private PreInstorageService preInstorageService;
	@Autowired
	private TransferHelper transferHelper;
	
	@Autowired
	private MDHouseConfigService mdHouseConfigService;
	@Autowired
	private MdSendOutTaskService mdSendOutTaskService;
	@Autowired
	private MDCheckInOrOutService mdCheckInOrOutService;
	
	/**
	 * 生成订单接口
	 * 包括入库预约单、正常单、退货入库单、盘点入库、盘点出库
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "anntoOrder", method = RequestMethod.POST)
	public void create(final HttpServletRequest request, final HttpServletResponse response) {
		try {
			mdExecutor.messageReceiverExecutor(request, new MdCallBackAdapter() {
				@Override
				public Response doBusiness(TransferData transferData) throws Exception {
					Response mdReponse = new Response();
					mdReponse.setFlag(true);
					// 报文内容
					TransferBodyContent body = TransferHelper.getTransferBodyContent(transferData);
					logger.info("mid request: {} | {}", body.getCustOrdNo(), body.getOrderType());
					String orderType = body.getOrderType();
					if (MDOrderType.SALE.getType().equals(orderType)) {
						doBusiness4Sale(transferData);
					} else if (MDOrderType.PURCHASE.getType().equals(orderType)) {
						doBusiness4Purchase(transferData);
					} else if (MDOrderType.RETURN.getType().equals(orderType)) {
						doBusiness4Back(transferData);
					} else if(MDOrderType.CHECKIN.getType().equals(orderType)
							|| MDOrderType.CHECKOUT.getType().equals(orderType)){
						doBusiness4CheckInOrOut(transferData,orderType);
					} else if(MDOrderType.REBACK.getType().equals(orderType) //返厂出库 07
							|| MDOrderType.REBACK.getType().equals(orderType)){
						doBusiness4Reback(transferData);
					} 
					return mdReponse;
				}
				
				private void doBusiness4Back(TransferData transferData) throws Exception {
					PreInstorageVo preInstorageVo = transferHelper.transferFromMidea4Back(transferData);
					preInstorageService.saveInstorageBillPre4MD(preInstorageVo, MDOrderType.RETURN);
				}
				

					private void doBusiness4Purchase(TransferData transferData) throws Exception {
						PreInstorageVo preInstorageVo = transferHelper.transferFromOrderPurChase(transferData);
						preInstorageService.saveInstorageBillPre4MD(preInstorageVo, MDOrderType.PURCHASE);
					}

				private void doBusiness4Sale(TransferData transferData) throws Exception {
					List<EdiOrder> orders = transferHelper.transferFromMidea4Order(transferData);
					ediOrderService.saveEdiOrder4MD(orders);
				}
				//返厂出库 07
				private void doBusiness4Reback(TransferData transferData) throws Exception {
					EdiOrder orders = transferHelper.transferFromMidea4Reback(transferData);
					//ediOrderService.saveEdiOrder4MD(orders);
					ulorderService.createBill_2(orders);
				}
				
				private void doBusiness4CheckInOrOut(TransferData transferData,String checkType) throws Exception {
					CheckInOrOut checkInOrOut = transferHelper.transferFromMidea4CheckInOrOut(transferData);
					mdCheckInOrOutService.saveCheckInOrOut4MD(checkInOrOut);
				}

				@Override
				public void doResponse(Response mdResponse) throws Exception {
					MidRestController.this.doResponse(mdResponse, response);
				}
			});
		} catch (PaiUException e) {
			logger.error("case some error.", e);
			Response mdResponse = new Response();
			mdResponse.setFlag(false);
			mdResponse.setErroCode(e.getErrorCode());
			mdResponse.setErro(e.getMessage());
			doResponse(mdResponse, response);
		} catch (Exception e) {
			logger.error("case some error.", e);
			Response mdResponse = new Response();
			mdResponse.setFlag(false);
			mdResponse.setErroCode(ErrorCode.DATA_ERROR.getCode());
			mdResponse.setErro(ErrorCode.DATA_ERROR.getMessage());
			doResponse(mdResponse, response);
		}
	}

	private void doResponse(Response reponse, HttpServletResponse response) {
		try {
			JAXB.marshal(reponse, response.getOutputStream());
		} catch (IOException e) {
			logger.error("case some error.", e);
		}
	}

	@RequestMapping(value = "stockQuery", method = RequestMethod.POST)
	public void queryStock(HttpServletRequest request, HttpServletResponse httpresponse) {
		String data = getData(request);
		logger.info("库存查询" + data);
		Response response = new Response();
		try {
			TransferData transferData = JAXB.unmarshal(new StringReader(data), TransferData.class);
			StockQueryRequestBody stockQueryRequestBody = (StockQueryRequestBody) transferData.getTransferBody().getContent();
			String wh_code = stockQueryRequestBody.getWhCode();
			MDHouseConfig mdHouseConfig=mdHouseConfigService.loadByMdWarehouseCode(wh_code);
			response.setFlag(true);
			response.setErro("");
			response.setErroCode("");
			if(mdHouseConfig != null)
			{
				String sku = stockQueryRequestBody.getCustGoodsCode();
				StockQueryResponseBody stockQueryResponseBody = new StockQueryResponseBody();
				List<StockQueryRecordDetail> list = new ArrayList<StockQueryRecordDetail>();
				if (sku == null || "".equals(sku)) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("EQ_customer.customerCode", "MID");
					map.put("EQ_mainWarehouseCode", mdHouseConfig.getPyWarehouseCode());
					QueryParamHolder paramHolder = new QueryParamHolder();
					paramHolder.setCurPage(1);
					paramHolder.setPageSize(Integer.MAX_VALUE);
					paramHolder.setSearchParams(map);
					Page<ViewMainCusStock> page = viewMainCusStockService.loadViewStock(paramHolder);
					for (ViewMainCusStock vs : page.getContent()) {
						StockQueryRecordDetail stockQueryRecordDetail = new StockQueryRecordDetail();
						stockQueryRecordDetail.setCustGoodsCode(vs.getBar());
						stockQueryRecordDetail.setGoodsStatus("normal");
						stockQueryRecordDetail.setQty(String.valueOf(vs.getSalesNum() + vs.getLockedNum()));
						stockQueryRecordDetail.setWhCode(wh_code);
						list.add(stockQueryRecordDetail);
					}
				} else {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("EQ_bar", sku);
					map.put("EQ_customer.customerCode", "MID");
					map.put("EQ_mainWarehouseCode", mdHouseConfig.getPyWarehouseCode());
					QueryParamHolder paramHolder = new QueryParamHolder();
					paramHolder.setCurPage(1);
					paramHolder.setPageSize(Integer.MAX_VALUE);
					paramHolder.setSearchParams(map);
					Page<ViewMainCusStock> page = viewMainCusStockService.loadViewStock(paramHolder);
					if(page.getContent().isEmpty())
					{
						response.setErro("SKU编码不存在");
						response.setErroCode("err01");
						response.setFlag(false);
					}
					else
					{
						StockQueryRecordDetail stockQueryRecordDetail = new StockQueryRecordDetail();
						stockQueryRecordDetail.setCustGoodsCode(sku);
						stockQueryRecordDetail.setGoodsStatus("normal");
						stockQueryRecordDetail.setQty(String.valueOf(page.getContent().get(0).getSalesNum() + page.getContent().get(0).getLockedNum()));
						stockQueryRecordDetail.setWhCode(wh_code);
						list.add(stockQueryRecordDetail);
					}
					
				}
				stockQueryResponseBody.setQueryDetails(list);
				ResponseBody responseBody = new ResponseBody();
				responseBody.setContent(stockQueryResponseBody);
				response.setResponseBody(responseBody);
			}
			else
			{
				response.setErro("仓库编码不存在");
				response.setErroCode("err01");
				response.setFlag(false);
			}
			JAXB.marshal(response, httpresponse.getWriter());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			response.setErro("查询出错");
			response.setErroCode("err01");
			response.setFlag(false);
			try {
				JAXB.marshal(response, httpresponse.getWriter());
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	@RequestMapping(value = "cancelOrder", method = RequestMethod.POST)
	public void cancelOrder(HttpServletRequest request, HttpServletResponse httpresponse) {
		String data = getData(request);
		logger.info("取消订单" + data);
		Response response = new Response();
		try {
			TransferData transferData = JAXB.unmarshal(new StringReader(data), TransferData.class);
			CancelOrderRequestBody cancelOrderRequestBody = (CancelOrderRequestBody) transferData.getTransferBody().getContent();
			String ordeno = cancelOrderRequestBody.getCustOrdNo();
			String order_type = cancelOrderRequestBody.getOrderType();
			if("01".equals(order_type))
			{
				List<WorkOrder> wos = workOrderService.loadByCustomerorderno(ordeno,WmsContants.CUSTOMER_MID);
				
				if (wos.isEmpty() || wos == null) {
					List<EdiOrder> ediOrders = ediOrderService.findByCustomerOrdeno(ordeno);
					if(ediOrders == null || ediOrders.isEmpty())
					{
						response.setErro("订单不存在");
						response.setFlag(false);
						response.setErroCode("err02");
					}
					else
					{
						for(EdiOrder eo : ediOrders)
						{
							workOrderService.cancelOrder(eo.getOrdeno(),"ADMIN");
						}
						response.setErro("取消成功");
						response.setFlag(true);
					}
				}
				else if(wos.size()==1)
				{
					String result = workOrderService.cancelOrder(wos.get(0).getOrder().getOrdeno(), "ADMIN");
					if ("success".equals(result)) {
						response.setErro("取消成功");
						response.setFlag(true);
						//防止拆单的一个在作业，一个未作业
						List<EdiOrder> ediOrders2 = ediOrderService.findByCustomerOrdeno(ordeno);
						for(EdiOrder eo : ediOrders2)
						{
							workOrderService.cancelOrder(eo.getOrdeno(),"ADMIN");
						}
					} else if ("sended".equals(result)) {
						response.setErro("已出库不能取消");
						response.setFlag(false);
						response.setErroCode("err03");
					} else if ("cancel".equals(result)) {
						response.setErro("已经取消");
						response.setFlag(true);
						response.setErroCode("err04");
					} else {
						response.setErro("取消失败");
						response.setFlag(false);
						response.setErroCode("err05");
					}
				}
				else {
					String flag = "yes";
					for(WorkOrder workOrder : wos)
					{
						if("6".equals(workOrder.getStatus()))
						{
							flag = "no";
						}
					}
					if("no".equals(flag))
					{
						response.setErro("已出库不能取消");
						response.setFlag(false);
						response.setErroCode("err021");
					}
					else
					{
						for(WorkOrder workOrder : wos)
						{
							 workOrderService.cancelOrder(workOrder.getOrder().getOrdeno(), "ADMIN");
						}
						response.setErro("取消成功");
						response.setFlag(true);
						//防止拆单的一个在作业，一个未作业
						List<EdiOrder> ediOrders2 = ediOrderService.findByCustomerOrdeno(ordeno);
						for(EdiOrder eo : ediOrders2)
						{
							workOrderService.cancelOrder(eo.getOrdeno(),"ADMIN");
						}
					}
				}
				
			}
			else if("02".equals(order_type)) // 采购入库
			{	
				preInstorageService.cancelPreOrderByCusNo(ordeno, WmsContants.CUSTOMER_MID);
				response.setErro("取消成功");
				response.setFlag(true);
			}
			else if("03".equals(order_type))// 退货入库
			{
				preInstorageService.cancelPreOrderByCusNo(ordeno, WmsContants.CUSTOMER_MID);
				response.setErro("取消成功");
				response.setFlag(true);
			}else if(MDOrderType.CHECKIN.getType().equals(order_type)
					|| MDOrderType.CHECKOUT.getType().equals(order_type))// 盘点出入库
			{
				this.mdCheckInOrOutService.cancelCheckInOrOut(ordeno, WmsContants.CUSTOMER_MID);
				response.setErro("取消成功");
				response.setFlag(true);
			}
			else if(MDOrderType.REBACK.getType().equals(order_type))// 返厂出库
			{
				this.ulorderService.cancelBill(ordeno);
				response.setErro("取消成功");
				response.setFlag(true);
			}
			
			JAXB.marshal(response, httpresponse.getWriter());
			//取消时，删除任务
			if(response.isFlag())
			{
				mdSendOutTaskService.deleteTaskByCusOrderNo(ordeno);
			}
		} catch (PaiUException e) {
			response.setErro(e.getMessage());
			response.setFlag(false);
			response.setErroCode(e.getErrorCode());
			try {
				JAXB.marshal(response, httpresponse.getWriter());
			} catch (IOException e1) {
			}
		}catch (Exception e) {
			response.setErro("服务器异常");
			response.setFlag(false);
			response.setErroCode("err06");
			try {
				JAXB.marshal(response, httpresponse.getWriter());
			} catch (IOException e1) {
			}
		}
	}

	public String getData(HttpServletRequest request) {
		String data = "";
		try {
			StringBuffer buffer = new StringBuffer();
			InputStream inputStream = request.getInputStream();
			byte[] bytes = new byte[1024];
			int count = inputStream.read(bytes);
			while (count != -1) {
				buffer.append(new String(bytes, 0, count, "UTF-8"));
				count = inputStream.read(bytes);
			}
			inputStream.close();
			data = buffer.toString();
		} catch (Exception e) {
			logger.info("获取数据错误");
		}

		return data;
	}

}
